package com.art.museumbackend.service.impl;

import com.art.museumbackend.entity.Admin;
import com.art.museumbackend.mapper.AdminMapper;
import com.art.museumbackend.service.AdminService;
import com.art.museumbackend.utils.Md5Util;
import com.art.museumbackend.utils.ThreadLocalUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author yezi
 * @since 2024-12-06
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {
    @Autowired
    private AdminMapper adminMapper;

    private static final int PASSWORD_EXPIRY_DAYS = 90; // 密码有效期90天
    private static final Pattern PASSWORD_PATTERN = Pattern.compile(
            "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,16}$"
    );

    @Override
    public Admin findByUsername(String username) {
        Admin admin = adminMapper.findByUsername(username);
        return admin;
    }

    @Override
    public void register(String username, String password) {
        if (!isPasswordValid(password)) {
            throw new RuntimeException("密码必须包含大小写字母、数字和特殊字符，长度在8-16位之间");
        }
        String MD5String = Md5Util.getMD5String(password);
        adminMapper.add(username, MD5String);
    }

    @Override
    public void updateInfo(Admin admin) {
        admin.setUpdateTime(LocalDateTime.now());
        adminMapper.updateInfo(admin);
    }

    @Override
    public void updateAvatar(String avatarUrl) {
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer id = (Integer) map.get("id");
        adminMapper.updateAvatar(avatarUrl, id);
    }

    @Override
    public void updatePwd(String newPwd) {
        if (!isPasswordValid(newPwd)) {
            throw new RuntimeException("密码必须包含大小写字母、数字和特殊字符，长度在8-16位之间");
        }
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer id = (Integer) map.get("id");
        adminMapper.updatePwd(Md5Util.getMD5String(newPwd), id);
    }

    @Override
    public void updateLoginFailInfo(Integer id, Integer failCount, Boolean lockStatus, LocalDateTime lockEndTime) {
        adminMapper.updateLoginFailInfo(id, failCount, lockStatus, lockEndTime);
    }

    @Override
    public void resetLoginFailInfo(Integer id) {
        adminMapper.resetLoginFailInfo(id);
    }

    @Override
    public void updateLastActivityTime(Integer id) {
        adminMapper.updateLastActivityTime(id);
    }

    @Override
    public boolean isAccountLocked(Admin admin) {
        if (admin == null || !Boolean.TRUE.equals(admin.getLockStatus())) {
            return false;
        }
        LocalDateTime now = LocalDateTime.now();
        return admin.getLockEndTime() != null && now.isBefore(admin.getLockEndTime());
    }

    @Override
    public boolean isPasswordExpired(Admin admin) {
        if (admin == null || admin.getPasswordUpdateTime() == null) {
            return true;
        }
        LocalDateTime now = LocalDateTime.now();
        long daysSinceUpdate = ChronoUnit.DAYS.between(admin.getPasswordUpdateTime(), now);
        return daysSinceUpdate >= PASSWORD_EXPIRY_DAYS;
    }

    @Override
    public boolean isPasswordValid(String password) {
        return PASSWORD_PATTERN.matcher(password).matches();
    }
}
